<template>
  <section class="cns-main-menu">
    <a-menu
      mode="inline"
      theme="dark"
      :openKeys.sync="openKeys"
      :inlineIndent="8"
      :selectedKeys="[selectKey]"
      :inline-collapsed="collapsed"
    >
      <template v-for="item in menus">
        <a-menu-item v-if="!item.children" :key="item.key" @click="changeMenu(item)">
          <app-menu-item :item="item" />
        </a-menu-item>
        <a-sub-menu v-else :key="item.key">
          <span slot="title">
            <app-menu-item :item="item" />
          </span>
          <template v-for="subitem in item.children">
            <a-menu-item v-if="!subitem.children" :key="subitem.key" @click="changeMenu(subitem)">
              <app-menu-item :item="subitem" />
            </a-menu-item>
            <a-sub-menu v-else :key="subitem.key">
              <span slot="title">
                <app-menu-item :item="subitem" />
              </span>
              <template v-for="sub1item in subitem.children">
                <a-menu-item
                  v-if="!sub1item.children"
                  :key="sub1item.key"
                  @click="changeMenu(sub1item)"
                >
                  <app-menu-item :item="sub1item" />
                </a-menu-item>
                <a-sub-menu v-else :key="sub1item.key">
                  <span slot="title">
                    <app-menu-item :item="sub1item" />
                  </span>
                  <template v-for="sub2item in sub1item.children">
                    <a-menu-item
                      v-if="!sub2item.children"
                      :key="sub2item.key"
                      @click="changeMenu(sub2item)"
                    >
                      <app-menu-item :item="sub2item" />
                    </a-menu-item>
                  </template>
                </a-sub-menu>
              </template>
            </a-sub-menu>
          </template>
        </a-sub-menu>
      </template>
    </a-menu>
  </section>
</template>

<script lang="ts">
import { ApiService } from "@/api";
import { AppConfig } from "@/config/config";
import { AppService } from "@/service/app-service";
import shared from "@/shared";
import qs from "qs";
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import AppMenuItem from "./app-menu-item.vue";

type MenuItem = {
  key: string;
  title: string;
  path: string;
  icon?: string;
  apptag?: string;
  funtag?: string;
  children?: MenuItem[];
};

@Component({
  components: {
    AppMenuItem
  }
})
export default class Menu extends Vue {
  /**
   * 是否收缩菜单
   */
  @Prop({ default: false }) collapsed!: boolean;

  /**
   * 菜单列表
   * key: 唯一 Key 值
   * title: 菜单标题
   * path: 菜单对应的路径
   */
  public menus: Array<any> = [];

  @Watch("$route")
  onPathChange(newVal: any, oldVal: any) {
    if (newVal.path !== oldVal.path) {
      this._initMenus();
    }
    const params: any = {};
    const _params: any = newVal.fullPath.slice(
      newVal.fullPath.indexOf("?") + 1
    );
    const paramArray: Array<string> = decodeURIComponent(_params).split(";");
    if (paramArray.length > 0) {
      paramArray.forEach((item: any) => {
        Object.assign(params, qs.parse(item));
      });
    }
    if (
      Object.prototype.hasOwnProperty.call(params, 'srfmenuname') &&
      params.srfmenuname &&
      this.selectKey !== params.srfmenuname
    ) {
      this.selectKey = params.srfmenuname;
    }
    const openKey = this.getParentMenu('', this.menus);
    if (openKey && this.openKeys.findIndex((key: string) => key === openKey) === -1) {
      this.openKeys.push(openKey)
    }
  }

  /**
   * 获取父菜单项
   * 
   * @memberof Menu
   */
  public getParentMenu(parentName: string, menus: any[]): string {
    let result: string = '';
    for (const menu of menus) {
      if (menu.key === this.selectKey) {
        result = parentName;
        break;
      }
      if (menu.children && menu.children.length) {
        result = this.getParentMenu(menu.key, menu.children);
        if (result) {
          break;
        }
      }
    }
    return result;
  }

  selectKey: string = "";

  openKeys: string[] = [];

  created() {
    ApiService.getInstance()
      .getMenus()
      .then((response: any) => {
        if (response && response.status === 200) {
          this.handleMenus(response.data);
          this._initMenus();
        }
      });
  }

  /**
   * vue生命周期 -- mounted
   *
   */
  public mounted() {
    setTimeout(() => {
      const el = document.getElementById("app-root-loading-x");
      if (el) {
        el.style.display = "none";
      }
    }, 1000);
  }
  /**
   * 处理菜单数据
   * 
[
            {
                key: "Home",
                title: "主页",
                path: "/"
            },
            {
                key: "randd",
                title: "randd 微应用",
                path: "/randd",
                children: [
                    {
                        key: "menuitem53",
                        title: "日志管理",
                        path: "/randd",
                        funtag: null,
                        apptag: "randd",
                        children: [
                            {
                                key: "menuitem79",
                                title: "登录用户日志管理",
                                path: "/randd",
                                funtag: "Auto6",
                                apptag: "randd"
                            },
                            {
                                key: "menuitem83",
                                title: "操作审计日志",
                                path: "/randd",
                                funtag: "AppFunc14",
                                apptag: "randd"
                            }
                        ]
                    }
                ]
            }
        ]
   *
   */
  public handleMenus(menus: Array<any>) {
    this.menus = [];
    if (menus && menus.length) {
      menus.forEach((menu: any) => {
        if (
          menu &&
          menu.system &&
          AppConfig.mountedSystems.indexOf(menu.system) !== -1
        ) {
          let appMenus: any = {
            key: menu.system,
            title: this.getLocaleCaption(menu),
            path: `/${menu.system}`
          };
          if (menu && menu.menuItems?.length > 0) {
            this.handleSingleAppMenus(menu.menuItems, appMenus, {
              path: `/${menu.system}`,
              appName: menu.app
            });
          }
          this.menus.push(appMenus);
        }
      });
    }
  }

  /**
   * 处理单个应用菜单数据
   *
   */
  public handleSingleAppMenus(source: any, target: any, args: any) {
    if (source && source.length > 0) {
      const { appName, path } = args;
      const childrenMenus: Array<any> = [];
      source.forEach((sourceMenuItem: any) => {
        const targetMenuItem = {
          key: `${appName}-${sourceMenuItem.tag}`,
          title: this.getLocaleCaption(sourceMenuItem),
          path: path,
          funtag: sourceMenuItem.funcTag,
          apptag: appName,
          icon: sourceMenuItem.icon
        };
        if (sourceMenuItem && sourceMenuItem.children?.length > 0) {
          this.handleSingleAppMenus(
            sourceMenuItem.children,
            targetMenuItem,
            args
          );
        }
        childrenMenus.push(targetMenuItem);
      });
      target.children = childrenMenus;
    }
  }

  private _initMenus() {
    const currentMenu = this._findCurrentMenu(
      this.menus,
      this.$route.path
    ) as MenuItem;
    if (!currentMenu) return;
    const { key } = currentMenu;
    this.selectKey = key;
  }

  private _findCurrentMenu(
    menus: MenuItem[],
    currentPath: string
  ): MenuItem | null {
    for (let i = 0; i < menus.length; i++) {
      const menu = menus[i];
      const { path } = menu;
      if (path === currentPath) return menu;

      const currentMenu = this._findCurrentMenu(
        menu.children || [],
        currentPath
      );
      if (currentMenu) return currentMenu;
    }
    return null;
  }

  /**
   * 切换菜单
   */
  private changeMenu(item: MenuItem) {
    const { key } = item;
    this.selectKey = key;
    if (item && item.path) {
      if (location.pathname !== item.path) {
        const loadContainer = document.getElementById(
          "child-container-loading"
        );
        if (loadContainer) {
          loadContainer.style.cssText = "display: block;";
        }
        setTimeout(() => {
          this.$router.push(item.path);
        }, 0);
      }
      // 微应用
      if (item.apptag && item.funtag) {
        AppService.getInstance().noticeMicroApp({
          tag: item.apptag,
          action: "MENUCLICK",
          data: item
        });
      } else {
        //基层应用
        setTimeout(() => {
          const tempRoute = {};
          Object.assign(tempRoute, {
            fullPath: this.$route.fullPath,
            ...this.$route.meta
          });
          shared.addPage(tempRoute);
        }, 0);
      }
    }
  }

  /**
   * 获取国际化标题
   */
  private getLocaleCaption(menu: any) {
    switch (this.$i18n.locale) {
      case 'zh-CN':
        return menu.caption;
      case 'en-US':
        return menu.caption2 ? menu.caption2 : menu.caption;
      case 'zh-TW':
      case 'zh-HK':
        return menu.caption3 ? menu.caption3 : menu.caption;
      default:
        return menu.caption;
    }
  }
}
</script>

<style lang="less" scoped>
.cns-main-menu {
  width: 100%;
  height: 100%;
  background: #001529;
  .cns-menu {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    width: 100%;
    a {
      color: #fff;
      text-decoration: none;
    }
  }
  .cns-parent-title {
    font-size: 13px;
    color: rgba(233, 241, 255, 0.75);
  }
  .cns-child-title {
    font-size: 13px;
    color: #fff;
  }
  .cns-child-title:hover {
    color: #408fff;
  }
  /deep/ .cns-menu-sub {
    background: rgb(12, 28, 53);
  }
}
</style>